package jfae.core.properties.parsers;

import java.beans.PropertyDescriptor;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Vector;

import jfae.core.properties.FieldInfo;
import jfae.core.properties.parsers.annotation.AnnotationHandler;

public abstract class AbstractAnnotationPropertyHandler<F extends FieldInfo<?>> implements PropertyHandler<F>{
	
	protected List<AnnotationHandler<?>> annHandlers = new Vector<AnnotationHandler<?>>();

	public AbstractAnnotationPropertyHandler(List<AnnotationHandler<?>> annHandlers) {
		super();
		this.annHandlers = annHandlers;
	}

	public F parse(PropertyDescriptor prop){
		F field = null;

		Class<?> type = prop.getPropertyType();
		field = buildFieldInfo(prop, type);
		
		if(field != null){
			Method readMethod = prop.getReadMethod();
			applyAnnotations(field, readMethod);
		}
		
		return field;
	}

	protected void applyAnnotations(FieldInfo<?> field, Method readMethod) {
		for (AnnotationHandler<?> handler : annHandlers) {
			applyAnnotationHandler(handler, field, readMethod);
		}
		
	}

	protected <T extends Annotation>void applyAnnotationHandler(AnnotationHandler<T> handler, FieldInfo<?> field, Method readMethod) {
		T annotation = readMethod.getAnnotation(handler.getType());
		if(annotation != null){
			handler.handle(annotation, field);
		}
	}

	protected abstract <T>F buildFieldInfo(PropertyDescriptor prop, Class<T> type);

}

